package com.ieslab.powergrid.demosvr.controller;

import com.ieslab.powergrid.demosvr.entity.MyException;
import com.ieslab.powergrid.demosvr.entity.Result;
import com.ieslab.powergrid.demosvr.service.TestAsyncService;
import com.ieslab.powergrid.demosvr.utils.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;

import java.util.*;
import java.util.Map.Entry;

/** <p>Title: TestController2 </p>
 * <p>Description: 测试全局异常捕获功能</p>
 *
 * @author houpeibin
 * @date 2020-2-20 下午7:15:30
 * @version V1.0
 */
@RestController
@Slf4j
public class TestController3 {
    @Autowired
    RedisClient redis;
    @Autowired
    private JedisPool jedisPool;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    TestAsyncService testAsyncService;


    @RequestMapping("del")
    public Result del(){
        long startTime = System.currentTimeMillis();
        try {
            jedisPool.getResource().flushAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("testRedis")
    public Result testRedis(int num){
        long startTime = System.currentTimeMillis();
        try {
            StringBuffer sb = new StringBuffer();
            for(int i=0;i<100;++i){
                sb.append("测试");
            }
            for(int i=0;i<num;i++){
                redis.set("rtd:" +i + ":1","ceshi1:"+ UUID.randomUUID()+sb.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("testRedis2")
    public Result testRedis2(int num,String type){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            StringBuffer sb = new StringBuffer();
            for(int i=0;i<100;++i){
                sb.append("测试");
            }
            //使用管道方式，性能比单次获取性能高
            jedis = jedisPool.getResource();
            Pipeline pipeline = jedis.pipelined();
            Map<String, Response<String>> map = new HashMap<>();
            for(int i=0;i<num;i++){
                try {
                    Response<String> sResponse= pipeline.set(("rtd:"+ i +":" + type),"ceshi:" + type + ":" + UUID.randomUUID()+sb.toString());
                    map.put(""+i,sResponse);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            pipeline.sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("testRedis3")
    public Result testRedis3(int num) {
        long startTime = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<100;++i){
            sb.append("测试");
        }
        /* 插入多条数据 */
        redisTemplate.executePipelined(new SessionCallback<Object>() {
            @Override
            public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
                for(int i=0;i<num;i++){
                    redisTemplate.opsForValue().set(("rtd:"+ i +":" + 1),"ceshi1:"+ UUID.randomUUID()+sb.toString());
                }
                return null;
            }
        });
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("getRedis")
    public Result getRedis(String type){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Set<String> keys = jedis.keys("type");
            log.info(".......keys:" + keys.size());
        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("getRedis2")
    public Result getRedis2(String type){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String keys = jedis.get("rtd:"+ type + ":1");
            log.info(".......keys:" + keys);
        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("getRedis3")
    public Result getRedis3(int type){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            for(int i=0;i<type;i++){
                jedis.get("rtd:"+ i +":2");
            }
        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }


    @RequestMapping("getRedis4")
    public Result getRedis4(int type, int num){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            //使用管道方式，性能比单次获取性能高
            Pipeline pipeline = jedis.pipelined();
            Map<String, Response<String>> map = new HashMap<>();
            for(int i=0;i<num;i++){
                try {
                    Response<String> sResponse= pipeline.get(("rtd:"+ i +":" + type));
                    map.put(""+i,sResponse);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            pipeline.sync();
            int i = num-10;
            for (Entry<String, Response<String>> entry : map.entrySet()) {
                Response<String> sResponse=(Response<String>)entry.getValue();
                if(i<num){
                   // if(sResponse.get() == null){
                        System.out.println(entry.getKey()+"-----" + sResponse.get());
                   // }
                }
                ++i;
            }
            System.out.println(map.size() + ":" + map.toString().getBytes().length/1024);


        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("getRedis41")
    public Result getRedis41(String key){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            //使用管道方式，性能比单次获取性能高
            Pipeline pipeline = jedis.pipelined();
            Map<String, Response<String>> map = new HashMap<>();
            Response<Set<String>> keys = pipeline.keys(key);
            pipeline.sync();
            Set<String> sets = keys.get();
           // System.out.println(System.currentTimeMillis() - startTime);
           // System.out.println("-----sets:" + sets.size());
            for(String ketTmp :sets){
                try {
                    Response<String> sResponse= pipeline.get(ketTmp);
                    map.put(ketTmp,sResponse);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            pipeline.sync();
            int i = sets.size()-10;
            for (Entry<String, Response<String>> entry : map.entrySet()) {
                Response<String> sResponse=(Response<String>)entry.getValue();
                if(i<sets.size()){
                    // if(sResponse.get() == null){
                   // System.out.println(entry.getKey()+"-----" + sResponse.get());
                    // }
                }
                ++i;
            }
            long haoshi = System.currentTimeMillis() - startTime;
            System.out.println("个数：" + map.size() + "；耗时:" + haoshi+ "；大小:" +  map.toString().getBytes().length/1024);


        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }
    @RequestMapping("getRedis42")
    public Result getRedis42(String key){
        long startTime = System.currentTimeMillis();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            //使用管道方式，性能比单次获取性能高
            Pipeline pipeline = jedis.pipelined();
            Map<String, Response<String>> map = new HashMap<>();
            Set<String> sets = jedisPool.getResource().keys(key);
            System.out.println(System.currentTimeMillis() - startTime);
            System.out.println("-----sets:" + sets.size());
            for(String ketTmp :sets){
                try {
                    Response<String> sResponse= pipeline.get(ketTmp);
                    map.put(ketTmp,sResponse);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            pipeline.sync();
            int i = sets.size()-10;
            for (Entry<String, Response<String>> entry : map.entrySet()) {
                Response<String> sResponse=(Response<String>)entry.getValue();
                if(i<sets.size()){
                    // if(sResponse.get() == null){
                    System.out.println(entry.getKey()+"-----" + sResponse.get());
                    // }
                }
                ++i;
            }
            System.out.println(map.size() + ":" + map.toString().getBytes().length/1024);


        } finally {
            //返还到连接池
            jedis.close();
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    @RequestMapping("getRedis43")
    public Result getRedis43(int num,String key){
        long startTime = System.currentTimeMillis();
        for (int i=0;i<num;++i){
            System.out.println(key+":启动");
            testAsyncService.getRedis433(key);
            System.out.println(key+":完成");
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }



    @RequestMapping("getRedis5")
    public Result getRedis5(String key){
        long startTime = System.currentTimeMillis();
        try {
            Set<String> sets = jedisPool.getResource().keys(key);
            List<String> keyList = new ArrayList<>();
            for(String ketTmp :sets){
                keyList.add(ketTmp);
            }
            List<Object> obj = batchGet(keyList);
            System.out.println(obj.size() + ":" + obj.toString().getBytes().length/1024);

        } finally {
            //返还到连接池
        }
        return Result.ok(System.currentTimeMillis() - startTime);
    }

    public List<Object> batchGet(List<String> keyList) {
        /* 批量获取多条数据 */
        List<Object> objects = redisTemplate.executePipelined((RedisCallback<String>) redisConnection -> {
            StringRedisConnection stringRedisConnection = (StringRedisConnection) redisConnection;
            for (String key : keyList) {
                stringRedisConnection.get(key);
            }
            return null;
        });

        return objects;
    }
}

